/*
    2D FDTD simulator
    Copyright (C) 2019 Emilia Blåsten

    This program is free software: you can redistribute it and/or
    modify it under the terms of the GNU Affero General Public License
    as published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public
    License along with this program.  If not, see
    <http://www.gnu.org/licenses/>.
*/
#include <SDL2/SDL.h>
#include <stdlib.h>
#include <stdio.h>
#include "plotWindow.h"
#include "plot2d.h"

Uint32 value2colour(plotWindow *plotter, double val) {
  double t;
  SDL_PixelFormat *format;
  format = plotter->surface->format;
  double red1 = plotter->red1;
  double green1 = plotter->green1;
  double blue1 = plotter->blue1;
  double red2 = plotter->red2;
  double green2 = plotter->green2;
  double blue2 = plotter->blue2;
  double maxf = plotter->maxf;
  double minf = plotter->minf;

  if( val >= 0 ) {
    val = fmin(val,maxf);
    t = val/maxf;
    return SDL_MapRGB( format, (Uint8)(t*red2+(1-t)*255),
      (Uint8)(t*green2+(1-t)*255), (Uint8)(t*blue2+(1-t)*255) );
  } else {
    val = fmax(val,minf);
    t = val/minf;
    return SDL_MapRGB( format, (Uint8)(t*red1+(1-t)*255),
      (Uint8)(t*green1+(1-t)*255), (Uint8)(t*blue1+(1-t)*255));
  }
}



void plot2d(double **array, int sizeX, int sizeY, plotWindow *plotter) {
  if(SDL_MUSTLOCK(plotter->surface)) {
    if(SDL_LockSurface(plotter->surface) < 0) return;
  }

  int width = plotter->surface->w;
  if(sizeX != width) {
    fprintf(stderr, "plotter width not same as sizeX.\n");
    exit(-1);
  }
  int mm, nn;
  for(mm = 0; mm < sizeX; mm++) {
    for(nn = 0; nn < sizeY; nn++) {
      ((Uint32*) plotter->surface->pixels)[nn*width + mm] =
        value2colour(plotter, array[mm][nn]);
    }
  }

  if(SDL_MUSTLOCK(plotter->surface)) SDL_UnlockSurface(plotter->surface);

  // Next, draw the pixels onto the window
  SDL_UpdateTexture(plotter->texture, NULL, plotter->surface->pixels,
    plotter->surface->pitch);
  SDL_RenderClear(plotter->renderer);
  SDL_RenderCopy(plotter->renderer, plotter->texture, NULL, NULL);
  SDL_RenderPresent(plotter->renderer);

  return;
}



void plot2dLinComb(double a1, double **array1, double a2, double **array2,
                   int sizeX, int sizeY, plotWindow *plotter) {
  if(SDL_MUSTLOCK(plotter->surface)) {
    if(SDL_LockSurface(plotter->surface) < 0) return;
  }

  int width = plotter->surface->w;
  if(sizeX != width) {
    fprintf(stderr, "plotter width not same as sizeX.\n");
    exit(-1);
  }
  int mm, nn;
  for(mm = 0; mm < sizeX; mm++) {
    for(nn = 0; nn < sizeY; nn++) {
      ((Uint32*) plotter->surface->pixels)[nn*width + mm] =
        value2colour(plotter, a1*array1[mm][nn] + a2*array2[mm][nn]);
    }
  }

  if(SDL_MUSTLOCK(plotter->surface)) SDL_UnlockSurface(plotter->surface);

  // Next, draw the pixels onto the window
  SDL_UpdateTexture(plotter->texture, NULL,
    plotter->surface->pixels, plotter->surface->pitch);
  SDL_RenderClear(plotter->renderer);
  SDL_RenderCopy(plotter->renderer, plotter->texture, NULL, NULL);
  SDL_RenderPresent(plotter->renderer);

  return;
}
